package com.ly.demo.thread.syn;

/**
 * @author liuyang
 * @des
 * @Version 1.0
 * @Date: 22/10/2021 10:17
 */
import lombok.SneakyThrows;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 4.使用重入锁实现线程同步
 *    ReentrantLock类是可重入、互斥、实现了Lock接口的锁，
 *    它与使用synchronized方法和快具有相同的基本行为和语义，并且扩展了其能力
 *    ReenreantLock类的常用方法有：
 *
 *        ReentrantLock() : 创建一个ReentrantLock实例
 *        lock() : 获得锁
 *        unlock() : 释放锁
 */
public class ReentrantLockSychronization {


    class Bank {
        private int account = 10;

        Lock lock = new ReentrantLock();


        public int getAccount() {
            return account;
        }


        public void saveAccount(int money) {
            lock.lock();
            try {
                account += money;
                System.out.println("account:" + account);
            } finally {
                lock.unlock();
            }
        }


    }

    class ReentrantThread implements Runnable {

        private Bank bank;

        public ReentrantThread(Bank bank) {
            this.bank = bank;
        }

        @SneakyThrows
        @Override
        public void run() {

            for (int i = 0; i < 10; i++) {
                bank.saveAccount(10);

                System.out.println(Thread.currentThread().getName() + "-->当前余额：" + bank.getAccount() + "元。");

//                Thread.sleep(3000);
            }

        }
    }


    public void userReentrantLockThread() {
        Bank bank = new Bank();
        ReentrantThread reentrantThread = new ReentrantThread(bank);

        Thread thread1 = new Thread(reentrantThread);
        Thread thread2 = new Thread(reentrantThread);

        thread1.start();
        thread2.start();


    }

    public static void main(String[] args) {
        ReentrantLockSychronization reentrantLockSychronization = new ReentrantLockSychronization();
        reentrantLockSychronization.userReentrantLockThread();
    }
}
